
/**
 *\file Population.c
 *\brief Code des fonctions du module Population
 *\details Intégralité du code de gestion de la population ainsi que les fonctions de test s'y rapportant
 *Une description de la structure Papulation est fournie à la rubrique
 *\link Population.h
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "Population.h"
#include "Personnage.h"


void initPopulation(Population* population)
{
    srand(time(NULL));

    population->membres = NULL;
    population->dernierPersonnage = NULL;
    population->effectifTotal = 0;
    population->fecondite = 5;
    population->mortalite = 5;
    population->immigration = 5;
    population->emigration = 5;
    population->moral = 100;
    population->nbPersonnagesAffames = 5 + rand()%45;
}

void creerPopulation(Population** population)
{
   TabComp *ptabComp = creerDonneeTabComp();
   *population = (Population*) malloc(sizeof(Population));
   initPopulation(*population);
   setTabCompPop(*population, ptabComp);
}

void ajouterMembre(Population* population)
{
    Personnage* personnage;
    TabComp *ptabComp = getTabCompPop(population);

    if(population->effectifTotal == 0)
    {
	personnage = creerCompletPers(ptabComp);
/*        creerPersonnage(&personnage,1,1,0);*/
        setIDPers(personnage,1);
	population->membres = personnage;
        population->dernierPersonnage = personnage;
        population->effectifTotal += 1;
    }
    else
    {
	personnage = creerCompletPers(ptabComp);
/*        creerPersonnage(&personnage,1,1,0);*/
        setIDPers(personnage,(population->dernierPersonnage->ID)+1);
        population->dernierPersonnage->personnageSuivant = personnage;
	personnage->personnagePrecedent = population->dernierPersonnage;
        population->dernierPersonnage = personnage;
        population->effectifTotal+= 1;
    }
}

void retirerMembre(Population* population, Personnage *personnage)
{
  int done;
  Personnage* tmp1;
  Personnage* tmp2;
  Personnage* personnagePrecedent;
  Personnage* personnageSuivant;

  tmp1 = population->dernierPersonnage;

  do
    {
      tmp2 = tmp1->personnagePrecedent;
      if(tmp1 == NULL)
	tmp2 = NULL;


      if(tmp1 == personnage)
	{
	  if(tmp1->personnageSuivant == NULL)
	    {
	      personnagePrecedent = personnage->personnagePrecedent;
	      population->dernierPersonnage = personnagePrecedent;
	      personnagePrecedent->personnageSuivant = NULL;
	      population->effectifTotal-= 1;
		  detruirePers(personnage);
	      done = 1;
	    }
	  else
	    {
	      if(tmp1->personnagePrecedent == NULL)
		{
		  personnageSuivant = personnage->personnageSuivant;
		  personnageSuivant->personnagePrecedent = NULL;
		  population->effectifTotal-= 1;
		  detruirePers(personnage);
		  done = 1;
		}
	      else
		{
		  personnagePrecedent = personnage->personnagePrecedent;
		  personnageSuivant = personnage->personnageSuivant;
		  personnagePrecedent->personnageSuivant = personnageSuivant;
		  personnageSuivant->personnagePrecedent = personnagePrecedent;
		  population->effectifTotal-= 1;
		  detruirePers(personnage);
		  done = 1;
		}
	    }
	}

      tmp1 = tmp2;
    }while(tmp2 != NULL && done != 1);
  

}

Personnage* getPersonnage(Population* population, const unsigned int ID)
{
    Personnage* etapeRecherche;
    etapeRecherche = population->membres;

    while(etapeRecherche != NULL)
    {
        if(etapeRecherche->ID == ID)
        {
            return etapeRecherche;
        }
    etapeRecherche = population->membres->personnagePrecedent;
    }
    return NULL;
}

unsigned int getEffectifTotal(Population* population)
{
    return population->effectifTotal;
}

int getFecondite(Population* population)
{
    return population->fecondite;
}

int getMortalite(Population* population)
{
    return population->mortalite;
}

int getImmigration(Population* population)
{
    return population->immigration;
}

int getEmigration(Population* population)
{
  return population->emigration;
}

int getMoral(Population* population)
{
    return population->moral;
}

unsigned int getNbPersAffames(Population* population)
{
    return (population->nbPersonnagesAffames * population->effectifTotal / 100);
}

TabComp *getTabCompPop(Population* population)
{
   return population->tabComp;
}

void setEffectifTotal(Population* population, const int varEffectif)
{
    population->effectifTotal += varEffectif;
}

void setFecondite(Population* population, const int varFecondite)
{
    population->fecondite += varFecondite;
}

void setMortalite(Population* population, const int varMortalite)
{
    population->mortalite += varMortalite;
}

void setImmigration(Population* population, const int varImmigration)
{
    population->immigration += varImmigration;
}

void setEmigration(Population* population, const int varEmigration)
{
    population->emigration += varEmigration;
}

void setMoral(Population* population, const int varMoral)
{
    population->moral += varMoral;
}

void setNbPersAffames(Population* population, unsigned int varNbPersAffames)
{
    population->nbPersonnagesAffames += varNbPersAffames;
}

void setTabCompPop(Population* population, TabComp *tabComp)
{
   population->tabComp = tabComp;
}

void detruireMembres(Population* population)
{
    Personnage* personnageActuel = population->dernierPersonnage;
    Personnage* personnagePrecedent = population->dernierPersonnage->personnagePrecedent;

    do
      {
        personnagePrecedent = personnageActuel->personnagePrecedent;
        detruirePers(personnageActuel);
        personnageActuel = personnagePrecedent;
      }    while(personnagePrecedent != NULL);


}

void detruirePopulation(Population* population)
{
   detruireMembres(population);
   detruireTabComp(population->tabComp);
   free(population);
}
